package com.firmboy.staticdb;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * CAS实现的测试类
 *
 * @author firmboy
 * @create 2018-04-17 上午10:35
 **/
public class Count {

    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            setState(count);
        }

        int getCount() {
            return getState();
        }


        @Override
        protected int tryAcquireShared(int acquires) {

            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                int nextc = c+1;
                if (compareAndSetState(c, nextc)){
                    return nextc;
                }
            }
        }

        @Override
        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0){
                    return false;
                }
                int nextc = c-1;
                if (compareAndSetState(c, nextc)){
                    return nextc == 0;
                }
            }
        }
    }

    private final Sync sync;

    public Count(){
        this.sync = new Sync(0);
    }


    public void inc(){
        sync.tryAcquireShared(1);
    }

    public void dec(){
        sync.tryReleaseShared(1);
    }

    public int getCount(){
        return sync.getCount();
    }

    public synchronized int getCountSyn(){
        int count = sync.getCount();
        sync.tryAcquireShared(1);
        return count;
    }

}
